package com.nanyang.tms.manager.waybill.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.nanyang.common.core.dict.CommonEnum;
import com.nanyang.common.core.page.PageBean;
import com.nanyang.common.core.page.PageTableBean;
import com.nanyang.common.tool.utils.json.JsonUtil;
import com.nanyang.common.tool.utils.uuid.GlobalIdGeneratorUtil;
import com.nanyang.commons.track.entity.request.ReqRegisterEntity;
import com.nanyang.commons.track.entity.request.ReqTrackEntity;
import com.nanyang.commons.track.entity.request.notify.Events;
import com.nanyang.commons.track.entity.request.notify.LatestStatus;
import com.nanyang.commons.track.entity.request.notify.TrackNotify;
import com.nanyang.commons.track.exception.TrackException;
import com.nanyang.commons.track.handle.TrackHandle;
import com.nanyang.tms.common.config.TmsConfig;
import com.nanyang.tms.common.contstant.TmsSerializeConstant;
import com.nanyang.tms.common.dict.TmsCommonEnum;
import com.nanyang.tms.common.exception.TmsManagerException;
import com.nanyang.tms.common.util.TmsExceptionUtil;
import com.nanyang.tms.dao.waybill.WaybillDao;
import com.nanyang.tms.dao.waybill.WaybillTrackDao;
import com.nanyang.tms.domain.waybill.WaybillTrackDO;
import com.nanyang.tms.domain.waybill.WaybillTrackQuery;
import com.nanyang.tms.domain.waybill.WaybillTrackVO;
import com.nanyang.tms.domain.waybill.WaybillVO;
import com.nanyang.tms.manager.waybill.WaybillTrackManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

@Slf4j
@Component("waybillTrackManager")
public class WaybillTrackManagerImpl implements WaybillTrackManager {
    @Autowired
    private WaybillTrackDao waybillTrackDao;
    @Autowired
    private WaybillDao waybillDao;
    @Autowired
    private TmsConfig tmsConfig;
    @Autowired
    private GlobalIdGeneratorUtil globalIdGeneratorUtil;
    @Override
    public PageBean<WaybillTrackVO> listWaybillTrack(WaybillTrackQuery query) {
        try {
            if (query == null) {
                log.error(TmsCommonEnum.PARAM_IS_NULL.getCode() + TmsCommonEnum.PARAM_IS_NULL.getMessage());
                throw new TmsManagerException(TmsCommonEnum.PARAM_IS_NULL.getCode() ,TmsCommonEnum.PARAM_IS_NULL.getMessage());
            }
            Integer count = waybillTrackDao.countTrack(query);
            PageBean<WaybillTrackVO> page = new PageTableBean<WaybillTrackVO>(query.getPageIndex(), query.getPageSize());
            if (null != count && count != 0) {
                page.setTotalItem(count);
                int startRow = page.getStartRow();
                if (startRow > 0) {
                    startRow -= 1;
                }
                query.setStartRow(startRow);
                page.addAll(waybillTrackDao.listTrack(query));
            }
            return page;
        } catch (Exception e) {
            throw TmsExceptionUtil.wrapException(e);
        }
    }
    @Override
    public void creatTrack(String supplierNo){
        try {
            ReqRegisterEntity reqRegisterEntity = new ReqRegisterEntity();
            reqRegisterEntity.setSk(tmsConfig.getTrackSk());
            reqRegisterEntity.setTrackUrl(tmsConfig.getTrackUrl());
            ReqTrackEntity reqTrackEntity =new ReqTrackEntity();
            reqTrackEntity.setNumber(supplierNo);
            List<ReqTrackEntity> list=new ArrayList<>();
            list.add(reqTrackEntity);
            reqRegisterEntity.setTrackList(list);
            TrackHandle.register(reqRegisterEntity);
        } catch (Exception e) {
            log.error("creatTrack:"+supplierNo,e);
            throw TmsExceptionUtil.wrapException(e);
        }
    }

    @Override
    @Transactional
    public void notifyTrack(String sign, String body) {
        try {
            if(StringUtils.isEmpty(sign)){
                throw new TmsManagerException(CommonEnum.ARG_NOTVALID.getCode(),String.format(CommonEnum.ARG_NOTVALID.getMessage(),"sign"));
            }
            if(StringUtils.isEmpty(body)){
                throw new TmsManagerException(CommonEnum.ARG_NOTVALID.getCode(),String.format(CommonEnum.ARG_NOTVALID.getMessage(),"body"));
            }
            String generatedSignature = TrackHandle.getGeneratedSignature(body, tmsConfig.getTrackSk());
            if(!generatedSignature.equals(sign)){
                throw new TmsManagerException(CommonEnum.NO_AUTH.getCode(),String.format(CommonEnum.NO_AUTH.getMessage()));
            }
            TrackNotify trackNotify = JsonUtil.fromJson(body, TrackNotify.class);
            System.out.println(JsonUtil.toJson(trackNotify));
            TrackNotify.TrackData data = trackNotify.getData();
            WaybillVO waybillVO = waybillDao.queryBySupplierNo(data.getNumber());
            if (ObjectUtil.isEmpty(waybillVO)){
                throw new TmsManagerException(CommonEnum.NO_CONTENT.getCode(),CommonEnum.NO_CONTENT.getMessage()+data.getNumber());
            }
            if(ObjectUtil.isEmpty(waybillVO.getTrackState())){//轨迹状态如果是null 说明第一次同步，要查出之前所有动态
                LatestStatus latest_status = data.getTrack_info().getLatest_status();
                if(latest_status.getStatus().equals("Delivered")){
                    waybillDao.updateTrackState(1,data.getNumber());
                }else if(latest_status.getStatus().equals("Exception")){
                    waybillDao.updateTrackState(2,data.getNumber());
                }else {
                    waybillDao.updateTrackState(0,data.getNumber());
                }
                List<Events> events = data.getTrack_info().getTracking().getProviders().get(0).getEvents();
                if(CollectionUtil.isNotEmpty(events)){
                    events.forEach(e ->{
                        WaybillTrackDO waybillTrackDO = bulidWaybillTrack(waybillVO,e);
                        waybillTrackDao.insert(waybillTrackDO);
                    });
                }
            }else if(waybillVO.getTrackState()==0){//轨迹状态如果是0 说明还在运输中
                LatestStatus latest_status = data.getTrack_info().getLatest_status();
                if(latest_status.getStatus().equals("Delivered")){
                    waybillDao.updateTrackState(1,data.getNumber());
                }else if(latest_status.getStatus().equals("Exception")){
                    waybillDao.updateTrackState(2,data.getNumber());
                }
                Events latest_event = data.getTrack_info().getLatest_event();
                if(ObjectUtil.isNotEmpty(latest_event)){
                    WaybillTrackDO waybillTrackDO = bulidWaybillTrack(waybillVO,latest_event);
                    waybillTrackDao.insert(waybillTrackDO);
                }
            }
        } catch (TrackException e) {
            log.error("notifyTrack:",e);
            throw TmsExceptionUtil.wrapException(e);
        }

    }

    private WaybillTrackDO bulidWaybillTrack(WaybillVO waybillVO,Events event){
        String recordSeq = TmsSerializeConstant.WAYBILL_TRACK_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.WAYBILL_TRACK_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
        WaybillTrackDO waybillTrack = WaybillTrackDO.builder()
                .trackCode(recordSeq)
                .waybillCode(waybillVO.getWaybillCode())
                .supplierNo(waybillVO.getSupplierNo())
                .companyCode(waybillVO.getCompanyCode())
                .content(event.getDescription())
                .address(event.getLocation())
                .trackTime(DateUtil.parseUTC(event.getTime_utc()).setTimeZone(TimeZone.getDefault()))
                .build();
        waybillTrack.setIp(waybillVO.getIp());
        waybillTrack.setGmtCreatePin(waybillVO.getGmtCreatePin());
        waybillTrack.setGmtModifiedPin(waybillVO.getGmtCreatePin());
        return waybillTrack;
    }
}
